import 'dart:convert';

import 'package:star_author/event_bus/rong_im_message_event.dart';
import 'package:star_author/provider/index.dart';
import 'package:star_author/utils/common_util/log_util.dart';
import 'package:star_author/utils/http/http_util.dart';
import 'package:star_author/utils/user_util.dart';
import 'package:get/get.dart';
import 'package:rongcloud_im_plugin/rongcloud_im_plugin.dart';
import 'package:sentry_flutter/sentry_flutter.dart';

import '../../config/base_configuration.dart';
import '../../event_bus/global_event_bus.dart';
import '../../event_bus/rong_im_message_come_event.dart';

//操作名称
class OperationKey {
  static const String send_words = 'RC:SendWordMsg'; //发送弹幕
  static const String start_explain = 'RC:StartExplainMsg'; //主播开始讲解
  static const String stop_live = "RC:StopLiveMsg"; //主播下播
  static const String join_explanation = "RC:JoinExplanation"; //加入讲解列表
  static const String join_chat_room = "RC:JoinChatRoom"; //进入直播间
  static const String interaction = "RC:Interaction"; //开放连麦申请
  static const String connecting_mic = "RC:ConnectingMic"; //立即连线用户--主播
  static const String close_connecting_mic =
      "RC:CloseConnectingMic"; //关闭连接用户--主播
  static const String user_to_connect =
      "RC:UserToConnect"; //用户点击立即连线后发送消息 主播端接收
  static const String change_anchor = "RC:ChangeAnchor"; //切换直播间的讲解人

  //开始连麦---弹幕
  static const String connecting_mic_barrage = "RC:ConnectingMicBarrage";

  //断开连麦--弹幕
  static const String close_connecting_mic_barrage =
      "RC:CloseConnectingMicBarrage";
}

class RongUtil {
  static String AppKey = "";

  static init() async {
    await RongIMClient.init(AppKey);
    Sentry.captureMessage(
        "初始化融云,AppKey:${AppKey},直播间Id:${UserUtil.getUserId(Get.context!)}");
    addListener();
  }

  static disconnect() {
    //needPush 断开连接之后是否需要远程推送
    RongIMClient.disconnect(false);
  }

  static Future<List?> getHistoryMessages() async {
    return await RongIMClient.getHistoryMessage(
        RCConversationType.ChatRoom, StreamConf.channelKey, -1, 100);
  }

  //求讲解货品 todo:///items 表示回流单信息
  static joinExplanation(
      UserProvider userProvider, Map<String, dynamic> items) async {
    TextMessage txtMessage = new TextMessage();
    Map map = {
      'operation': OperationKey.join_explanation,
      'data': {
        "is_bidder": userProvider.isBidder,
        "user_level": userProvider.user!['level'],
        "user_nickname": userProvider.user!['mask_nickname'],
        "backflows": items,
      }
    };
    txtMessage.extra = json.encode(map);
    Message? msg = await RongIMClient.sendMessage(
        RCConversationType.ChatRoom, StreamConf.channelKey, txtMessage);

    RongIMClient.onMessageSend =
        (int? messageId, int? status, int? code) async {
      if (status == RCSentStatus.Sent) {
        if (msg != null) {
          Message? message = await RongIMClient.getMessage(msg.messageId!);
          GlobalEventBus().bus.fire(RongIMMessageEvent(message!));
        }
      }
    };
  }

  static joinChatRoomEvent(UserProvider userProvider) async {
    TextMessage txtMessage = new TextMessage();
    Map map = {
      'operation': OperationKey.join_chat_room,
      'data': {
        "is_bidder": userProvider.isBidder,
        "user_level": userProvider.user!['level'],
        "user_nickname": userProvider.user!['mask_nickname'],
        "cover": userProvider.user!['avatar'],
      }
    };
    txtMessage.extra = json.encode(map);
    Message? msg = await RongIMClient.sendMessage(
        RCConversationType.ChatRoom, StreamConf.channelKey, txtMessage);

    RongIMClient.onMessageSend =
        (int? messageId, int? status, int? code) async {
      if (status == RCSentStatus.Sent) {
        if (msg != null) {
          Message? message = await RongIMClient.getMessage(msg.messageId!);
          GlobalEventBus().bus.fire(RongIMMessageComeEvent(message!));
        }
      }
    };
  }

  static Future<Message?> sendMsg(
    String text,
    UserProvider userProvider, {
    Map param: const {},
  }) async {
    TextMessage txtMessage = new TextMessage();
    txtMessage.content = text;

    Map map = {
      'operation': OperationKey.send_words,
      'data': {
        "is_bidder": userProvider.isBidder,
        "id": userProvider.user!['id'],
        "user_level": userProvider.user!['level'],
        "user_nickname": userProvider.user!['mask_nickname'],
        "words": text,
        "cover": userProvider.user!['avatar'],
      }
    };
    if (param.isNotEmpty) {
      //被艾特人的信息
      map['be_user_info'] = param;
      text = text.replaceAll("@" + param['user_nickname'] + "", "");
      map['data']['words'] = text.trimLeft().trimRight();
      txtMessage.content = text.trimLeft().trimRight();
    }
    LogUtil.v("发送消息map：${map}");
    txtMessage.extra = json.encode(map);
    MentionedInfo mentionedInfo = MentionedInfo()
      ..userIdList = [
        "${param['id'] ?? 0}",
      ]
      ..type = RCMentionedType.Users;
    if (param.isNotEmpty) {
      txtMessage.mentionedInfo = mentionedInfo;
    }

    Message? msg = await RongIMClient.sendMessage(
        RCConversationType.ChatRoom, StreamConf.channelKey, txtMessage);
    LogUtil.v("发送的消息为：${msg?.toString()}");
    return msg;
  }

  static joinChatRoom() async {
    await RongIMClient.joinExistChatRoom(StreamConf.channelKey, 20);
  }

  static quitChatRoom() async {
    await RongIMClient.quitChatRoom(StreamConf.channelKey);
  }

  static addListener() {
    //消息接收回调
    RongIMClient.onMessageReceived = (Message? msg, int? left) {
      LogUtil.v("receive message messsageId:" +
          msg!.messageId.toString() +
          " left:" +
          left.toString());
      if (msg.targetId == StreamConf.channelKey) {
        GlobalEventBus().bus.fire(RongIMMessageEvent(msg));
      }
    };
  }

  static Future<int?> getChatRoomCount() async {
    ChatRoomInfo? chatRoomInfo = (await RongIMClient.getChatRoomInfo(
        StreamConf.channelKey, 20, RCChatRoomMemberOrder.Asc));
    if (chatRoomInfo == null) return 0;
    return chatRoomInfo.totalMemeberCount ?? 0;
  }

  //from: user   anchor
  static connect(Function connectResult, String form) async {
    int status = await RongIMClient.getConnectionStatus() ?? 0;
    if (status == RCConnectionStatus.Connected) {
      LogUtil.v("当前已经连接");
      Sentry.captureMessage("当前已经连接");
      connectResult();
    } else {
      await HttpUtil.commonRequest(
        Get.context!,
        "/api/v1/obtain_rong_cloud_im_token/",
        isLoading: false,
        isErrorToast: false,
        method: HttpUtil.MethodPost,
      ).then((value) async {
        if (value.data != null) {
          await RongIMClient.connect(value.data['token'],
              (int? code, String? userId) {
            LogUtil.v('连接状态码: ' + code.toString());
            if (code != RCErrorCode.Success) {
              Sentry.captureMessage("连接状态码:${code},用户Id:${userId}");
            }
            if (code == 34001) {
              connectResult();
            }
            if (code == 31004 || code == 12) {
              LogUtil.v("token过期");
              Sentry.captureMessage("token过期");
              // if (form == "anchor") {
              //   connect(connectResult, form);
              // }
              // connect(connectResult);
            } else if (code == 0) {
              connectResult();
              LogUtil.v("connect userId" + userId!);
              // 连接成功后打开数据库
              // _initUserInfoCache();
            }
          });
        }
      });
    }
  }

  static Future<bool> recallMessage(messageId) async {
    // 此处 Message 必须是一个的已发送消息，可以通过监听 onMessageSend 回调的 messageId 调用 getMessage 方法获取到新发送的消息
    var message = await RongIMClient.getMessage(messageId);
    var recallNotifiMessage =
        await RongIMClient.recallMessage(message, "撤回了一条消息");
    LogUtil.v("recallNotifiMessage:${recallNotifiMessage?.encode()}");
    if (recallNotifiMessage != null) {
      // 消息发送者撤回成功，更新消息列表移除或标记被撤回消息
      return true;
    } else {
      //撤回失败
      return false;
    }
  }

  //统一用一个操作方法
  static operation(String operation, Map<String, dynamic> data) async {
    TextMessage txtMessage = new TextMessage();
    Map map = {
      'operation': operation,
      'data': data,
    };
    txtMessage.extra = json.encode(map);
    Message? msg = await RongIMClient.sendMessage(
        RCConversationType.ChatRoom, StreamConf.channelKey, txtMessage);
    if ([OperationKey.connecting_mic, OperationKey.close_connecting_mic]
        .contains(operation)) {
      sendToBarrage(data, msg);
    }
  }

  //需要发送到弹幕的消息
  static sendToBarrage(data, msg) async {
    TextMessage txtMessage = new TextMessage();
    Map map2 = {
      'data': data,
    };
    if (data['connect_type'] == 'disconnect') {
      //断开连麦
      map2['operation'] = OperationKey.close_connecting_mic_barrage;
    } else if (data['connect_type'] == 'connect') {
      //断开连麦
      map2['operation'] = OperationKey.connecting_mic_barrage;
    }
    txtMessage.extra = json.encode(map2);
    Message? msg2 = await RongIMClient.sendMessage(
        RCConversationType.ChatRoom, StreamConf.channelKey, txtMessage);
    RongIMClient.onMessageSend =
        (int? messageId, int? status, int? code) async {
      if (status == RCSentStatus.Sent) {
        if (msg2 != null) {
          LogUtil.v("消息发送成功:推送到弹幕");
          Message? message = await RongIMClient.getMessage(msg2.messageId!);
          GlobalEventBus().bus.fire(RongIMMessageEvent(message!));
        }
      }
    };
  }
}
